package com.xlhj.boot.service;

import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName RedisService
 * @Description redis业务接口
 * @Author liucaijing
 * @Date 2020/10/9 23:32
 * @Version 1.0
 */
public interface RedisService {

    /**
     * 查看所有key
     * @param pattern key *
     * @return
     */
    Set<String> keys(String pattern);

    /**
     * 查询key是否存在
     * @param key
     * @return
     */
    Boolean existsKey(String key);

    /**
     * 查看key类型
     * @param key
     * @return
     */
    DataType type(String key);

    /**
     * 删除key
     * @param key
     * @return
     */
    Boolean delete(String key);

    /**
     * 根据value选择非阻塞删除
     * @param key
     * @return
     */
    Boolean unlink(String key);

    /**
     * 给指定key设置过期时间
     * @param key
     * @param times
     * @param timeUnit
     * @return
     */
    Boolean expireKey(String key, long times, TimeUnit timeUnit);

    /**
     * 查看还是多少秒过期
     * @param key
     * @return -1表示不过期，-2表示已过期
     */
    Long ttl(String key);

    /**
     * 设置key-value
     * @param key
     * @param value
     */
    void set(String key, String value);

    /**
     * 设置带过期时间的key-value
     * @param key
     * @param value
     * @param times
     */
    void set(String key, String value, long times);

    /**
     * 获取key的值
     * @param key
     * @return
     */
    String get(String key);

    /**
     * 将给定的value追加到原值末尾
     * @param key
     * @param value
     * @return
     */
    Integer append(String key, String value);

    /**
     * 获取值的长度
     * @param key
     * @return
     */
    Long strlen(String key);

    /**
     * 当key不存在时，设置key的值
     * @param key
     * @param value
     * @return
     */
    Boolean setnx(String key, String value);

    /**
     * 将key中的数字增1
     * @param key
     * @return
     */
    Long incr(String key);

    /**
     * 将key中数字减1
     * @param key
     * @return
     */
    Long decr(String key);

    /**
     * 将key中数字增自定义步长
     * @param key
     * @param step
     * @return
     */
    Long incrby(String key, long step);

    /**
     * 将key中数字减自定义步长
     * @param key
     * @param step
     * @return
     */
    Long decrby(String key, long step);

    /**
     * 同时设置一个或多个值
     * @param map
     */
    void mset(Map<String, String> map);

    /**
     * 同时获取一个或多个值
     * @param keys
     * @return
     */
    List<String> mget(List<String> keys);

    /**
     * 同时设置一个或多个值，仅当key都不存在
     * @param map
     * @return
     */
    Boolean msetnx(Map<String, String> map);

    /**
     * 获取值的范围，前后都包括
     * @param key
     * @param start
     * @param stop
     * @return
     */
    String getrange(String key, long start, long stop);

    /**
     * 设置键值的同时，设置过期时间
     * @param key
     * @param expire
     * @param value
     */
    void setex(String key, int expire, String value);

    /**
     * 设置新值同时获取旧值
     * @param key
     * @param value
     * @return
     */
    String getset(String key, String value);

    /**
     * 获取分布式锁
     * @return
     */
    Long getDistributedLock();

    /**
     * 简单限流 period秒最大执行maxCount次
     * @param key
     * @param period
     * @param maxCount
     * @return
     */
    Boolean SimpleRateLimiter(String key, long period, int maxCount);

    /**
     * 漏洞限流
     * @param key
     * @param capacity
     * @param leakingRate
     * @return
     */
    Boolean FunnelRateLimiter(String key, int capacity, float leakingRate);

    /**
     * 向list中左边插入一个值
     * @param key
     * @param value
     * @return
     */
    Long lpush(String key, String value);

    /**
     * 向list中左边插入多个值
     * @param key
     * @param value
     * @return
     */
    Long lpush(String key, String... value);

    /**
     * 向list右边插入一个值
     * @param key
     * @param value
     * @return
     */
    Long rpush(String key, String value);

    /**
     * 向list右边插入多个值
     * @param key
     * @param value
     * @return
     */
    Long rpush(String key, String... value);

    /**
     * 从list左边取出一个值
     * @param key
     * @return
     */
    String lpop(String key);

    /**
     * 从list右边取出一个值
     * @param key
     * @return
     */
    String rpop(String key);

    /**
     * 从list key1右边取出一个值，插到key2左边
     * @param key1
     * @param key2
     * @return
     */
    String rpoplpush(String key1, String key2);

    /**
     * 按照索引下标获取元素 当start=0/stop=-1时表示获取所有
     * @param key
     * @param start
     * @param stop
     * @return
     */
    List<String> lrange(String key, int start, int stop);

    /**
     * 按照索引下标获取元素
     * @param key
     * @param index
     * @return
     */
    String lindex(String key, int index);

    /**
     * 获取key长度
     * @param key
     * @return
     */
    Long llen(String key);

    /**
     * 在oldValue后面插入newValue
     * @param key
     * @param oldValue
     * @param newValue
     * @return
     */
    Long linsert(String key, String oldValue, String newValue);

    /**
     * 从左边删除n个value
     * @param key
     * @param num
     * @param value
     * @return
     */
    Long lrem(String key, int num, String value);

    /**
     * 将key下标为index的值替换成value
     * @param key
     * @param index
     * @param value
     */
    void lset(String key, int index, String value);

    /**
     * 将一个或多个member元素加入set集合，已经存在的member元素将被忽略
     * @param key
     * @param value
     * @return
     */
    Long sadd(String key, String... value);

    /**
     * 取出set集合中所有值
     * @param key
     * @return
     */
    Set<String> smembers(String key);

    /**
     * 判断set集合中是否含有value值
     * @param key
     * @param value
     * @return
     */
    Boolean sismember(String key, String value);

    /**
     * 返回set集合元素个数
     * @param key
     * @return
     */
    Long scard(String key);

    /**
     * 删除集合中某个元素
     * @param key
     * @param value
     * @return
     */
    Long srem(String key, String... value);

    /**
     * 随机从set集合取出一个值
     * @param key
     * @return
     */
    String spop(String key);

    /**
     * 随机从set集合取出n个值，不会删除
     * @param key
     * @param num
     * @return
     */
    List<String> srandmember(String key, int num);

    /**
     * 把set集合中一个值从一个集合移动到另一个集合
     * @param sourceKey
     * @param value
     * @param destKey
     * @return
     */
    Boolean smove(String sourceKey, String value, String destKey);

    /**
     * 返回两个集合的交集
     * @param key1
     * @param key2
     * @return
     */
    Set<String> sinter(String key1, String key2);

    /**
     * 返回两个集合的并集
     * @param key1
     * @param key2
     * @return
     */
    Set<String> sunion(String key1, String key2);

    /**
     * 返回两个集合的差集
     * @param key1
     * @param key2
     * @return
     */
    Set<String> sdiff(String key1, String key2);

    /**
     * 给hash集合中field赋值value
     * @param key
     * @param field
     * @param value
     */
    void hset(String key, String field, String value);

    /**
     * 获取hash集合field的值
     * @param key
     * @param field
     * @return
     */
    Object hget(String key, String field);

    /**
     * 批量设置hash的值
     * @param key
     * @param map
     */
    void hmset(String key, Map<String, Object> map);

    /**
     * 查看hash表key中，给定field是否存在
     * @param key
     * @param field
     * @return
     */
    Boolean hexists(String key, String field);

    /**
     * 列出该hash集合所有field
     * @param key
     * @return
     */
    Set<Object> hkeys(String key);

    /**
     * 列出hash集合中所有value
     * @param key
     * @return
     */
    List<Object> hvals(String key);

    /**
     * 为hash key中field的值加上增量1 或 -1
     * @param key
     * @param field
     * @param increment
     * @return
     */
    Long hincrby(String key, String field, int increment);

    /**
     * 将hash表key中的field的值设为value，当且仅当field不存在
     * @param key
     * @param field
     * @param value
     * @return
     */
    Boolean hsetnx(String key, String field, String value);

    /**
     * 将一个或多个member元素及其score值加入到zset中
     * @param key
     * @param value
     * @param score
     * @return
     */
    Boolean zadd(String key, String value, double score);

    /**
     * 返回下标在start和stop之间的元素
     * @param key
     * @param start
     * @param stop
     * @return
     */
    Set<String> zrange(String key, long start, long stop);

    /**
     * 返回下标在start和stop之间的元素包括分数
     * @param key
     * @param start
     * @param stop
     * @return
     */
    Set<ZSetOperations.TypedTuple<String>> zrangewithscore(String key, long start, long stop);

    /**
     * 返回所有score值介于min和max之间的元素，并按score递增排序
     * @param key
     * @param min
     * @param max
     * @return
     */
    Set<String> zrangebyscore(String key, double min, double max);

    /**
     * 返回所有score值介于min和max之间的元素，并按score递减排序
     * @param key
     * @param min
     * @param max
     * @return
     */
    Set<String> zrevrangebyscore(String key, double min, double max);

    /**
     * 为zset的score加增量
     * @param key
     * @param value
     * @param increment
     * @return
     */
    Double zincrby(String key, String value, int increment);

    /**
     * 删除zset下指定元素
     * @param key
     * @param value
     * @return
     */
    Long zrem(String key, String value);

    /**
     * 统计zset分数区间内元素个数
     * @param key
     * @param min
     * @param max
     * @return
     */
    Long zcount(String key, double min, double max);

    /**
     * 返回在zset中排名，从0开始
     * @param key
     * @param value
     * @return
     */
    Long zrank(String key, String value);

    /********************Bitmaps命令操作********************/
    /**
     * 设置bitmaps中偏移量offset的值
     * @param key
     * @param offset 偏移量
     * @param value 值 1:true;0:false
     * @return
     */
    boolean setbit(String key, long offset, boolean value);

    /**
     * 获取bitmaps中偏移量的值
     * @param key
     * @param offset 从0开始
     * @return
     */
    Boolean getbit(String key, long offset);

    /**
     * 统计key从start字节到end字节比特值为1的数量
     * @param key
     * @param start
     * @param end
     * @return
     */
    Long bigcount(String key, long start, long end);

    /**
     * 获取多个bitmaps的交集/并集/非/异或并保存结果到destkey中
     * @param operation 操作符 AND, OR, XOR, NOT
     * @param destKey 结果key
     * @param keys
     */
    void bitop(RedisStringCommands.BitOperation operation, String destKey, String... keys);

    /********************HyperLogLog命令操作********************/
    /**
     * 添加元素到hyperloglog
     * @param key
     * @param value
     * @return
     */
    Long pfadd(String key, String... value);

    /**
     * 统计多个值
     * @param keys
     * @return
     */
    Long pfcount(String... keys);

    /**
     * 将一个或多个hll合并后保存到destkey
     * @param destKey
     * @param sourceKeys
     * @return
     */
    Long pfmerge(String destKey, String... sourceKeys);

    /********************Geospatial命令操作********************/
    /**
     * 添加地理位置
     * @param key
     * @param longitude 经度
     * @param latitude 纬度
     * @param member 名称
     * @return
     */
    Long geoadd(String key, double longitude, double latitude, String member);

    /**
     * 获取指定地区坐标值
     * @param key
     * @param members
     * @return
     */
    List<Point> geopos(String key, String... members);

    /**
     * 获取两个位置的直线距离
     * @param key
     * @param member1
     * @param member2
     * @return
     */
    Distance geodist(String key, String member1, String member2);

    /**
     * 给定经纬度为中心，找出某半径内的值
     * @param key
     * @param longitude
     * @param latitude
     * @param radius
     */
    void georadius(String key, double longitude, double latitude, double radius);

    /**
     * 给定地理位置为中心，找出某一半径内的值
     * @param key
     * @param member
     * @param radius
     */
    void georadius(String key, String member, double radius);
}
